package main

import (
	"fmt"
	"strconv"
)

func main() {
	/*
		type: 用于类型定义和类型别名

			1.类型定义：type 类型名 Type
			2.类型别名：type 类型名 = Type

		type:
			1.type 用于给类型起别名
			2.给整个函数起 type，简化代码
			3.定义结构体
			4.定义自定义类型

		注：非本地类型不能定义方法
			即，不能为不在一个包中的类型定义方法
			解决方法：（1）在当前包中，为该非本地类型定义新类型：type newType oldType
					（2）将该类型的别名定义在该类型的包中

		給类型起别名：
		（1）解决新旧包的迁移兼容问题
		（2）解决新旧类型的迁移问题
		（3）Go的按包进行隔离的机制不太精细，有时我们需要将大包划分为几个小包进行开发，但需要在大包里面暴露全部的类型给使用者
	*/
	var i1 myint
	var i2 = 100 //int
	i1 = 200
	fmt.Println(i1, i2)

	var name mystring
	name = "喜羊羊"
	var s1 string
	s1 = "小灰灰"
	fmt.Println(name, s1)

	//i1 = i2 // cannot use i2 (variable of type int) as type myint in assignment
	//name = s1 //cannot use s1 (variable of type string) as type mystring in assignment

	fmt.Printf("%T   %T   %T   %T\n", i1, i2, name, s1) //main.myint   int   main.mystring   string

	fmt.Println("----------------------------------")
	res1 := fun11()
	fmt.Println(res1(10, 20))

	fmt.Println("----------------------------------")
	var i3 myint2
	i3 = 100
	fmt.Println(i3)
	i3 = i2
	fmt.Println(i3)
	fmt.Printf("%T   %T   %T\n", i1, i2, i3) //main.myint   int   int
}

// 1.定义一个新的类型
type myint int
type mystring string

// 2.定义一个函数类型
type myfun func(int, int) string

func fun11() myfun {
	fun := func(a, b int) string {
		s := strconv.Itoa(a) + strconv.Itoa(b)
		return s
	}
	return fun
}

// 3.类型别名
type myint2 = int //不是重新定义新的数据类型，只是给 int 起别名，和 int 可以通用
